home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: delta / whiteline CD Series - delta.iso / progtool / c / egem_210 / egem / source / window.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-25  |  20.0 KB  |  970 lines

  1.  
  2. #include <stdarg.h>
  3. #include <string.h>
  4. #include "proto.h"
  5.  
  6. #define WINCREATED    1
  7. #define WINOPENED    100
  8.  
  9. static void send_winmsg(WIN *window,int msg_id,int msg4,int msg5,int msg6,int msg7)
  10. {
  11.     int msg[8];
  12.  
  13.     msg[3] = window->handle;
  14.     msg[4] = msg4;
  15.     msg[5] = msg5;
  16.     msg[6] = msg6;
  17.     msg[7] = msg7;
  18.     _send_puf(msg_id,msg);
  19. }
  20.  
  21. void CycleCloseWindows(char cycle_hot,char close_hot,int cycle_menu,int close_menu)
  22. {
  23.     _cycle_hot = UpperChar(cycle_hot);
  24.     _close_hot = UpperChar(close_hot);
  25.  
  26.     _cycle = cycle_menu;
  27.     _close = close_menu;
  28.  
  29.     _set_menu();
  30. }
  31.  
  32. void _cycle_close_window(int cycle,int titel)
  33. {
  34.     reg WIN *window,*wins,*last;
  35.     int mbuf[8];
  36.  
  37.     if (_dia_len==0 && _popup==0)
  38.     {
  39.         if (titel>0)
  40.             menu_select(titel,0);
  41.  
  42.         if (_opened>0)
  43.         {
  44.             if (cycle && _opened==1)
  45.                 return;
  46.  
  47.             if ((window=get_top_window())!=NULL)
  48.             {
  49.                 if (cycle)
  50.                 {
  51.                     wins = window+1;
  52.                     last = &_windows[MAX_WINDOWS];
  53.                     while (wins<last)
  54.                         if (wins->handle>0)
  55.                             break;
  56.                         else
  57.                             wins++;
  58.  
  59.                     if (wins>=last)
  60.                     {
  61.                         last = window;
  62.                         wins = _windows;
  63.                         while (wins<last)
  64.                             if (wins->handle>0)
  65.                                 break;
  66.                             else
  67.                                 wins++;
  68.                     }
  69.                 }
  70.                 else
  71.                     wins = window;
  72.                 mbuf[3] = wins->handle;
  73.                 _send_puf((cycle) ? WIN_TOPPED : WIN_CLOSED,mbuf);
  74.             }
  75.         }
  76.     }
  77. }
  78.  
  79. #define DEFAULT_WINW 72
  80. #define DEFAULT_WINH 72
  81.  
  82. int cdecl _default_icfs(int type,...)
  83. {
  84.     reg int bitpos, x, *c, ret = -1;
  85.     reg unsigned long mask = 1L;
  86.     va_list pp;
  87.     static unsigned long pos = 0L;
  88.  
  89.     va_start(pp,type);
  90.     if (type==ICF_GETPOS)
  91.     {
  92.         bitpos = 0;
  93.         x = desk.g_x;
  94.  
  95.         do
  96.         {
  97.             if ((pos & mask)==0L)
  98.             {
  99.                 pos |= mask;
  100.                 ret = bitpos+1;
  101.                 break;
  102.             }
  103.  
  104.             bitpos++;
  105.             x += DEFAULT_WINW;
  106.             mask<<=1;
  107.         }
  108.         while (bitpos<32 && (x+DEFAULT_WINW)<=desk.g_x+desk.g_w);
  109.  
  110.         if (ret>0)
  111.         {
  112.             c = va_arg(pp,int*);
  113.             *c = x;
  114.             c = va_arg(pp,int*);
  115.             *c = desk.g_y+desk.g_h-DEFAULT_WINH;
  116.             c = va_arg(pp,int*);
  117.             *c = DEFAULT_WINW;
  118.             c = va_arg(pp,int*);
  119.             *c = DEFAULT_WINH;
  120.         }
  121.     }
  122.     else if (type==ICF_FREEPOS)
  123.     {
  124.         bitpos = va_arg(pp,int)-1;
  125.         if (bitpos>=0 && bitpos<=31)
  126.         {
  127.             if (bitpos>0)
  128.                 mask <<= bitpos;
  129.             pos &= ~mask;
  130.             ret = 0;
  131.         }
  132.     }
  133.     else
  134.         ret = -32;
  135.  
  136.     va_end(pp);
  137.     return (ret);
  138. }
  139.  
  140. static void AvWin(int handle,int init)
  141. {
  142.     if (AvServer>=0)
  143.     {
  144.         int msg[8];
  145.         msg[3] = handle;
  146.         AvSendMsg(AvServer,(init) ? AV_ACCWINDOPEN : AV_ACCWINDCLOSED,msg);
  147.     }
  148. }
  149.  
  150. int _icfs_iconify(WIN *window,int iconify,int old_top)
  151. {
  152.     reg int handle = window->handle;
  153.  
  154.     if (iconify)
  155.     {
  156.         int x,y,w,h;
  157.  
  158.         if (win_iconified(window))
  159.             return (TRUE);
  160.         else if (!(window->gadgets & SMALLER))
  161.             return (FAIL);
  162.         else if ((window->posnr=(*_icfs)(ICF_GETPOS,&x,&y,&w,&h))>0)
  163.         {
  164.             reg int top = (old_top==FALSE) ? _get_top() : old_top;
  165.  
  166.             if (top==handle)
  167.                 top = FALSE;
  168.  
  169.             wind_close(handle);
  170.             wind_delete(handle);
  171.  
  172.             window->iconified |= ICFS;
  173.  
  174.             window->handle = wind_create(NAME|MOVER,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  175.             window_name(window,window->name,window->icon_name);
  176.             wind_open(window->handle,x,y,w,h);
  177.             wind_xget(window->handle,WF_WORKXYWH,&window->icf_work.g_x,&window->icf_work.g_y,&window->icf_work.g_w,&window->icf_work.g_h);
  178.  
  179.             if (top>=0)
  180.                 wind_set(_last_top = (top>0) ? top : window->handle,WF_TOP);
  181.  
  182.             if (handle!=window->handle && window->av_win)
  183.             {
  184.                 AvWin(handle,FALSE);
  185.                 AvWin(window->handle,TRUE);
  186.             }
  187.  
  188.             return (TRUE);
  189.         }
  190.         else
  191.             return (FALSE);
  192.     }
  193.     else
  194.     {
  195.         if (window->iconified & ICFS)
  196.         {
  197.             wind_close(handle);
  198.             wind_delete(handle);
  199.  
  200.             window->iconified &= ~ICFS;
  201.  
  202.             window->handle = wind_create(window->gadgets,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  203.             window_name(window,window->name,window->icon_name);
  204.             window_info(window,window->info);
  205.             wind_set(window->handle,WF_BEVENT,_back_win);
  206.  
  207.             if (window->gadgets & HSLIDE)
  208.             {
  209.                 wind_set(window->handle,WF_HSLIDE,window->sl_hpos);
  210.                 wind_set(window->handle,WF_HSLSIZE,window->sl_hsize);
  211.             }
  212.  
  213.             if (window->gadgets & VSLIDE)
  214.             {
  215.                 wind_set(window->handle,WF_VSLIDE,window->sl_vpos);
  216.                 wind_set(window->handle,WF_VSLSIZE,window->sl_vsize);
  217.             }
  218.  
  219.             wind_open(_last_top=window->handle,window->curr.g_x,window->curr.g_y,window->curr.g_w,window->curr.g_h);
  220.             (*_icfs)(ICF_FREEPOS,window->posnr);
  221.  
  222.             if (handle!=window->handle && window->av_win)
  223.             {
  224.                 AvWin(handle,FALSE);
  225.                 AvWin(window->handle,TRUE);
  226.             }
  227.         }
  228.  
  229.         return (TRUE);
  230.     }
  231. }
  232.  
  233. int _get_top(void)
  234. {
  235.     int top,dummy;
  236.  
  237.     wind_xget(0,WF_TOP,&top,&dummy,&dummy,&dummy);
  238.     return (top);
  239. }
  240.  
  241. WIN *get_top_window(void)
  242. {
  243.     WIN *win = get_window(_get_top());
  244.     if (win)
  245.         _last_top = win->handle;
  246.     return (win);
  247. }
  248.  
  249. WIN *get_window(int handle)
  250. {
  251.     reg WIN *window = _windows;
  252.     reg int i;
  253.  
  254.     if (handle<=0)
  255.         return (NULL);
  256.  
  257.     for (i=MAX_WINDOWS;--i>=0;window++)
  258.         if (window->handle==handle)
  259.             return (window);
  260.  
  261.     return (NULL);
  262. }
  263.  
  264. void window_top(WIN *win)
  265. {
  266.     if (_dia_len>0 || _popup)
  267.     {
  268.         send_winmsg(win,WIN_TOPPED,0,0,0,0);
  269.         win->inside = FAIL;
  270.     }
  271.     else
  272.     {
  273.         wind_set(_last_top=win->handle,WF_TOP);
  274.         _window_fast_mouse(win,TRUE);
  275.     }
  276. }
  277.  
  278. void window_bottom(WIN *win)
  279. {
  280.     if (_bottom)
  281.     {
  282.         if (_dia_len>0 || _popup)
  283.             send_winmsg(win,WM_BOTTOMED,0,0,0,0);
  284.         else
  285.         {
  286.             wind_set(win->handle,WF_BOTTOM);
  287.             if (get_top_window()==NULL && _last_top==win->handle)
  288.                 _last_top = FAIL;
  289.         }
  290.         win->inside = FAIL;
  291.     }
  292. }
  293.  
  294. int window_first(WIN *win,GRECT *rect)
  295. {
  296.     return (wind_xget(win->handle,WF_FIRSTXYWH,&rect->g_x,&rect->g_y,&rect->g_w,&rect->g_h));
  297. }
  298.  
  299. int window_next(WIN *win,GRECT *rect)
  300. {
  301.     return (wind_xget(win->handle,WF_NEXTXYWH,&rect->g_x,&rect->g_y,&rect->g_w,&rect->g_h));
  302. }
  303.  
  304. void _window_fast_mouse(WIN *window,int top)
  305. {
  306.     window->inside = FAIL;
  307.  
  308.     if (_popup==0 && _dia_len==0 && (top || get_top_window()==window))
  309.     {
  310.         if (!window->iconified)
  311.         {
  312.             SCROLL *sc = window->scroll;
  313.             GRECT area;
  314.             int x,y;
  315.  
  316.             area = window->work;
  317.             if (sc)
  318.             {
  319.                 area.g_x += sc->tbar_l;
  320.                 area.g_y += sc->tbar_u;
  321.                 area.g_w -= sc->tbar_l+sc->tbar_r;
  322.                 area.g_h -= sc->tbar_u+sc->tbar_d;
  323.             }
  324.  
  325.             _mouse_pos(&x,&y);
  326.             if ((window->inside=rc_inside(x,y,&area))!=0)
  327.             {
  328.                 if (window->mouse_in>=0)
  329.                     graf_mouse(window->mouse_in,window->mouse_inform);
  330.             }
  331.             else if (window->mouse_out>=0)
  332.                 graf_mouse(window->mouse_out,window->mouse_outform);
  333.         }
  334.         else if (window->mouse_out>=0)
  335.             graf_mouse(window->mouse_out,window->mouse_outform);
  336.     }
  337. }
  338.  
  339. void _reset_mouse(void)
  340. {
  341.     WIN *window;
  342.  
  343.     if (_dia_len==0 && _popup==0 && (window=get_top_window())!=NULL)
  344.         _window_fast_mouse(window,TRUE);
  345. }
  346.  
  347. void window_mouse(WIN *window)
  348. {
  349.     _window_fast_mouse(window,FALSE);
  350. }
  351.  
  352. void window_set_mouse(WIN *window,int in,int out,MFORM *in_form,MFORM *out_form)
  353. {
  354.     if (window->dialog!=NULL)
  355.         in = out = FAIL;
  356.  
  357.     window->mouse_in = in;
  358.     window->mouse_out = out;
  359.     window->mouse_inform = in_form;
  360.     window->mouse_outform = out_form;
  361.     window_mouse(window);
  362. }
  363.  
  364. WIN *open_window(char *title,char *icon_title,char *info,OBJECT *icon,int typ,int box,int min_w,int min_h,GRECT *max_curr,GRECT *curr,SCROLL *scroll,void (*redraw)(WIN *,GRECT *))
  365. {
  366.     reg int handle,i,av_win = (AvServer>=0 && _no_av_win==0);
  367.     reg WIN *window,*win;
  368.     int x,y;
  369.  
  370.     _no_av_win = 0;
  371.  
  372.     if (_dia_len>0 || _popup)
  373.         return (NULL);
  374.  
  375.     for (i=MAX_WINDOWS,window=_windows;--i>=0;window++)
  376.         if (window->handle<=0)
  377.             break;
  378.  
  379.     if (i<0)
  380.         return(NULL);
  381.  
  382.     if (title)
  383.         typ |= NAME;
  384.  
  385.     if (info)
  386.         typ |= INFO;
  387.  
  388.     if (magx)
  389.         typ |= BACKDROP;
  390.  
  391.     if (max_curr==NULL)
  392.         max_curr = &desk;
  393.  
  394.     handle = wind_create(typ,desk.g_x,desk.g_y,desk.g_w,desk.g_h);
  395.     if (handle>0)
  396.     {
  397.         for (i=MAX_WINDOWS,win=_windows;--i>=0;win++)
  398.             if (win->handle>0)
  399.                 win->inside = FAIL;
  400.  
  401.         window->handle = handle;
  402.         window->vdi_handle = x_handle;
  403.         window->gadgets = typ;
  404.  
  405.         window->min_w = max(min_w,(gr_cw*12));
  406.         window->min_h = max(min_h,(gr_ch*4));
  407.         window->icon = icon;
  408.         window->redraw = (void *) redraw;
  409.         window->scroll = scroll;
  410.         window->curr = *curr;
  411.         window->max = *max_curr;
  412.         window->sl_hpos = window->sl_hsize = window->sl_vpos = window->sl_vsize = -1000;
  413.  
  414.         if (typ & NAME)
  415.             window_name(window,title,icon_title);
  416.  
  417.         if (typ & INFO)
  418.             window_info(window,info);
  419.  
  420.         if (_back_win && _bevent)
  421.             wind_set(handle,WF_BEVENT,1);
  422.  
  423.         window_size(window,curr);
  424.         curr = &window->curr;
  425.  
  426.         if (box)
  427.             graf_growbox(max_w>>1,max_h>>1,1,1,curr->g_x,curr->g_y,curr->g_w,curr->g_h);
  428.  
  429.         wind_open(_last_top=handle,curr->g_x,curr->g_y,curr->g_w,curr->g_h);
  430.         window->opened = WINOPENED;
  431.  
  432.         _mouse_pos(&x,&y);
  433.         window->inside = rc_inside(x,y,&window->work);
  434.         window->mouse_in = window->mouse_out = FAIL;
  435.         window->av_win = av_win;
  436.  
  437.         if (av_win)
  438.             AvWin(handle,TRUE);
  439.  
  440.         _opened++;
  441.         _set_menu();
  442.  
  443.         return (window);
  444.     }
  445.     else
  446.         return (NULL);
  447. }
  448.  
  449. void window_reinit(WIN *win,char *title,char *icon_title,char *info,int home)
  450. {
  451.     SCROLL *sc = win->scroll;
  452.  
  453.     if (sc && home)
  454.         sc->hpos = sc->vpos = sc->px_hpos = sc->px_vpos = 0;
  455.  
  456.     window_name(win,title,icon_title);
  457.     window_info(win,info);
  458.  
  459.     win->opened = WINCREATED;
  460.     window_size(win,&win->curr);
  461.     win->opened = WINOPENED;
  462.  
  463.     redraw_window(win,NULL);
  464. }
  465.  
  466. int close_window(WIN *window,int box)
  467. {
  468.     reg int handle = window->handle, exit = TRUE;
  469.  
  470.     if (handle>0)
  471.     {
  472.         if (!_ac_close && (_dia_len>0 || _popup))
  473.         {
  474.             send_winmsg(window,WM_CLOSED,0,0,0,0);
  475.             return (FALSE);
  476.         }
  477.  
  478.         if (box && !_ac_close)
  479.             graf_shrinkbox(max_w>>1,max_h>>1,1,1,window->work.g_x,window->work.g_y,window->work.g_w,window->work.g_h);
  480.  
  481.         if (window->iconified & ICFS)
  482.             (*_icfs)(ICF_FREEPOS,window->posnr);
  483.  
  484.         if (window->av_win && (!_ac_close || multi))
  485.             AvWin(handle,FALSE);
  486.  
  487.         memset(window,0,sizeof(WIN));
  488.         _opened = max(_opened-1,0);
  489.  
  490.         _set_menu();
  491.  
  492.         if (!_ac_close)
  493.         {
  494.             if (!wind_close(handle) || !wind_delete(handle))
  495.                 exit = FALSE;
  496.             if (get_top_window()==NULL && _last_top==handle)
  497.                 _last_top = FAIL;
  498.             _reset_mouse();
  499.         }
  500.     }
  501.     else
  502.         exit = FALSE;
  503.  
  504.     return (exit);
  505. }
  506.  
  507. void window_name(WIN *win,char *name,char *icon_name)
  508. {
  509.     win->name = name;
  510.     win->icon_name = icon_name;
  511.  
  512.     if (win->gadgets & NAME)
  513.     {
  514.         if (win_iconified(win) && icon_name)
  515.             name = icon_name;
  516.  
  517.         if (name==NULL)
  518.             name = "";
  519.  
  520.         if (_dia_len>0 || _popup)
  521.             send_winmsg(win,WIN_NAME,(int) (((long) name)>>16),(int) name,0,0);
  522.         else
  523.             wind_set(win->handle,WF_NAME,name);
  524.     }
  525. }
  526.  
  527. void window_info(WIN *win,char *info)
  528. {
  529.     win->info = info;
  530.  
  531.     if ((win->gadgets & INFO) && !(win->iconified & ICFS))
  532.     {
  533.         if (info==NULL)
  534.             info = "";
  535.         if (_dia_len>0 || _popup)
  536.             send_winmsg(win,WIN_INFO,(int) (((long) info)>>16),(int) info,0,0);
  537.         else
  538.             wind_set(win->handle,WF_INFO,info);
  539.     }
  540. }
  541.  
  542. void window_border(int kind,int x,int y,int w_in,int h_in,GRECT *out)
  543. {
  544.     out->g_x = out->g_y = 0;
  545.     out->g_w = w_in;
  546.     out->g_h = h_in;
  547.     window_calc(WC_BORDER,kind,out,out);
  548.     out->g_x = max(x,desk.g_x);
  549.     out->g_y = max(y,desk.g_y);
  550.     Min(&out->g_w,desk.g_w);
  551.     Min(&out->g_h,desk.g_h);
  552. }
  553.  
  554. void window_calc(int type,int kind,GRECT *in,GRECT *out)
  555. {
  556.     wind_calc(type,kind,in->g_x,in->g_y,in->g_w,in->g_h,
  557.               &out->g_x,&out->g_y,&out->g_w,&out->g_h);
  558. }
  559.  
  560. WIN *window_find(int x,int y)
  561. {
  562.     return (get_window(wind_find(x,y)));
  563. }
  564.  
  565. void window_scroll_slider(WIN *win,int vh)
  566. {
  567.     reg SCROLL *sc = win->scroll;
  568.     reg long pos,size;
  569.     reg int max_h,max_v;
  570.  
  571.     pos = size = 1000;
  572.     if (vh==HOR_SLIDER)
  573.     {
  574.         if (!(win->gadgets & HSLIDE))
  575.             return;
  576.         else if ((max_h=sc->hsize-sc->hpage)>0)
  577.         {
  578.             pos *= sc->hpos;
  579.             pos /= max_h;
  580.  
  581.             size *= sc->hpage;
  582.             size /= sc->hsize;
  583.         }
  584.         else
  585.             pos = 0;
  586.     }
  587.     else if (!(win->gadgets & VSLIDE))
  588.         return;
  589.     else if ((max_v=sc->vsize-sc->vpage)>0)
  590.     {
  591.         pos *= sc->vpos;
  592.         pos /= max_v;
  593.         size *= sc->vpage;
  594.         size /= sc->vsize;
  595.     }
  596.     else
  597.         pos = 0;
  598.  
  599.     window_slider(win,vh,(int) pos,(int) size);
  600. }
  601.  
  602. void window_size(WIN *win,GRECT *size)
  603. {
  604.     GRECT curr = *size,work;
  605.     reg DIAINFO *info = (DIAINFO *) win->dialog;
  606.     reg SCROLL *sc = win->scroll;
  607.     reg int old_h,old_v;
  608.  
  609.     Max(&curr.g_x,win->max.g_x);
  610.     Max(&curr.g_y,win->max.g_y);
  611.  
  612.     curr.g_w = max(min(curr.g_w,win->max.g_w),win->min_w);
  613.     curr.g_h = max(min(curr.g_h,win->max.g_h),win->min_h);
  614.  
  615.     win->fulled = rc_equal(&curr,&win->max);
  616.     win->prev = win->curr;
  617.  
  618.     if (sc)
  619.     {
  620.         Max(&sc->px_hline,1);
  621.         Max(&sc->px_vline,1);
  622.  
  623.         old_h = sc->hpos;
  624.         old_v = sc->vpos;
  625.  
  626.         window_calc(WC_WORK,win->gadgets,&curr,&work);
  627.  
  628.         sc->hpage = max((work.g_w-sc->tbar_l-sc->tbar_r)/sc->px_hline,1);
  629.         sc->vpage = max((work.g_h-sc->tbar_u-sc->tbar_d)/sc->px_vline,1);
  630.  
  631.         if (win->opened)
  632.         {
  633.             sc->hpos = max(min(sc->hpos,sc->hsize-sc->hpage),0);
  634.             sc->vpos = max(min(sc->vpos,sc->vsize-sc->vpage),0);
  635.         }
  636.         else
  637.             sc->hpos = sc->vpos = sc->px_hpos = sc->px_vpos = 0;
  638.  
  639.         if (_dial_round && info==NULL)
  640.             work.g_x &= ~7;
  641.  
  642.         work.g_w = sc->tbar_l + sc->tbar_r + (sc->hpage*sc->px_hline);
  643.         work.g_h = sc->tbar_u + sc->tbar_d + (sc->vpage*sc->px_vline);
  644.  
  645.         win->work = work;
  646.         window_calc(WC_BORDER,win->gadgets,&work,&curr);
  647.     }
  648.     else
  649.         window_calc(WC_WORK,win->gadgets,&curr,&win->work);
  650.  
  651.     win->curr = curr;
  652.  
  653.     if (win->opened)
  654.     {
  655.         _window_fast_mouse(win,FALSE);
  656.         if (!win_iconified(win))
  657.         {
  658.             if (_dia_len>0 || _popup)
  659.                 send_winmsg(win,WM_SIZED,curr.g_x,curr.g_y,curr.g_w,curr.g_h);
  660.             else
  661.                 wind_set(win->handle,WF_CURRXYWH,curr.g_x,curr.g_y,curr.g_w,curr.g_h);
  662.         }
  663.     }
  664.  
  665.     if (info)
  666.     {
  667.         reg OBJECT *tree = info->di_tree;
  668.  
  669.         *(GRECT *) &tree->ob_x = win->work;
  670.         tree->ob_x += info->di_xy_off;
  671.         tree->ob_y += info->di_xy_off;
  672.         tree->ob_width -= info->di_wh_off;
  673.         tree->ob_height -= info->di_wh_off;
  674.     }
  675.  
  676.     if (sc)
  677.     {
  678.         window_scroll_slider(win,HOR_SLIDER);
  679.         window_scroll_slider(win,VERT_SLIDER);
  680.         if (win->opened==WINOPENED && (old_h!=sc->hpos || old_v!=sc->vpos))
  681.         {
  682.             scroll_window(win,WIN_SCROLL,NULL);
  683.             _send_msg(win,0,WIN_SCROLLED,old_h,old_v);
  684.         }
  685.     }
  686. }
  687.  
  688. static void set_slide(WIN *win,int set_id,int msg_id,int val)
  689. {
  690.     if (_dia_len>0 || _popup)
  691.         send_winmsg(win,msg_id,val,0,0,0);
  692.     else
  693.         wind_set(win->handle,set_id,val);
  694. }
  695.  
  696. void window_slider(WIN *win,int dir,int pos,int size)
  697. {
  698.     reg int set = !(win->iconified & ICFS);
  699.  
  700.     pos = min(pos,1000);
  701.  
  702.     if (dir!=HOR_SLIDER)
  703.     {
  704.         if (win->gadgets & VSLIDE)
  705.         {
  706.             if (pos>=0 && win->sl_vpos!=pos)
  707.             {
  708.                 win->sl_vpos = pos;
  709.                 if (set)
  710.                     set_slide(win,WF_VSLIDE,WIN_VSLIDE,pos);
  711.             }
  712.  
  713.             if (size>0 && win->sl_vsize!=size)
  714.             {
  715.                 win->sl_vsize = size;
  716.                 if (set)
  717.                     set_slide(win,WF_VSLSIZE,WIN_VSLSIZE,size);
  718.             }
  719.         }
  720.     }
  721.     else if (win->gadgets & HSLIDE)
  722.     {
  723.         if (pos>=0 && win->sl_hpos!=pos)
  724.         {
  725.             win->sl_hpos = pos;
  726.             if (set)
  727.                 set_slide(win,WF_HSLIDE,WIN_HSLIDE,pos);
  728.         }
  729.  
  730.         if (size>0 && win->sl_hsize!=size)
  731.         {
  732.             win->sl_hsize = size;
  733.             if (set)
  734.                 set_slide(win,WF_HSLSIZE,WIN_HSLSIZE,size);
  735.         }
  736.     }
  737. }
  738.  
  739. void redraw_window(WIN *win,GRECT *area)
  740. {
  741. #ifndef SMALL_EGEM
  742.     EDINFO ed;
  743. #endif
  744.     GRECT cursor,work,mouse,m_work;
  745.     reg int redraw = !win_iconified(win),clipped,mouse_off;
  746.     reg OBJECT *icon;
  747.     reg DIAINFO *info = (DIAINFO *) win->dialog;
  748.     reg SCROLL *sc = win->scroll;
  749.     int d,pxy[4];
  750.  
  751.     if (sc)
  752.     {
  753.         sc->px_hpos = sc->hpos*sc->px_hline;
  754.         sc->px_vpos = sc->vpos*sc->px_vline;
  755.     }
  756.  
  757.     if (area==NULL)
  758.         area = &desk;
  759.     else if (!rc_intersect(&desk,area))
  760.         return;
  761.  
  762.     if ((redraw && win->redraw==NULL) || (_dia_len|_popup))
  763.     {
  764.         int msg[8];
  765.  
  766.         msg[3] = win->handle;
  767.         *(GRECT *) &msg[4] = *area;
  768.         _send_puf(WM_REDRAW,msg);
  769.         return;
  770.     }
  771.  
  772.     if (info!=NULL)
  773.     {
  774.         info->di_cursor = FALSE;
  775.         info->di_drawn = TRUE;
  776.     }
  777.  
  778.     if (redraw)
  779.     {
  780.         icon = NULL;
  781.  
  782.     #ifndef SMALL_EGEM
  783.         if (info && win->iconified==0 && _edit_get_info(info->di_tree,info->di_ed_obj,info->di_ed_index,&ed))
  784.         {
  785.             _calc_cursor(info,&ed,&cursor);
  786.             info->di_cursor = TRUE;
  787.         }
  788.     #endif
  789.     }
  790.     else
  791.         icon = (win->icon) ? win->icon : iconified;
  792.  
  793.     if (icon)
  794.     {
  795.         icon->ob_x = win->icf_work.g_x + ((win->icf_work.g_w - icon->ob_width)>>1);
  796.         icon->ob_y = win->icf_work.g_y + ((win->icf_work.g_h - icon->ob_height)>>1);
  797.     }
  798.  
  799.     graf_mkstate(&mouse.g_x,&mouse.g_y,&d,&d);
  800.     mouse.g_x -= 16;
  801.     mouse.g_y -= 16;
  802.     mouse.g_w = 32;
  803.     mouse.g_h = 32;
  804.     rc_intersect(&desk,&mouse);
  805.  
  806.     wind_update(BEG_UPDATE);
  807.     clipped = mouse_off = FALSE;
  808.     window_first(win,&work);
  809.     while (work.g_w>0 && work.g_h>0)
  810.     {
  811.         if (rc_intersect(area,&work))
  812.         {
  813.             if (!mouse_off)
  814.             {
  815.                 m_work = work;
  816.                 if ((mouse_off=rc_intersect(&mouse,&m_work))!=0)
  817.                     MouseOff();
  818.             }
  819.  
  820.             if (redraw)
  821.             {
  822.                 rc_grect_to_array(&work,pxy);
  823.                 vs_clip(win->vdi_handle,1,pxy);
  824.                 clipped = (win->vdi_handle==x_handle);
  825.  
  826.                 if (info)
  827.                     (*(D_PROC) win->redraw)(info,&work,&cursor);
  828.                 else
  829.                     (*(R_PROC) win->redraw)(win,&work);
  830.             }
  831.             else
  832.             {
  833.                 _clip_rect(&work);
  834.                 clipped = TRUE;
  835.                 rc_sc_clear(&work);
  836.                 if (icon)
  837.                     objc_draw(icon,0,MAX_DEPTH,work.g_x,work.g_y,work.g_w,work.g_h);
  838.             }
  839.         }
  840.         window_next(win,&work);
  841.     }
  842.  
  843.     if (clipped)
  844.         _clip_rect(&desk);
  845.     if (mouse_off)
  846.         MouseOn();
  847.     wind_update(END_UPDATE);
  848. }
  849.  
  850. void _arrow_window(SCROLL *sc,int mode,int speed)
  851. {
  852.     switch (mode)
  853.     {
  854.     case WA_LFPAGE:
  855.         sc->hpos -= max(sc->hpage-sc->hscroll,1)*speed;break;
  856.     case WA_UPPAGE:
  857.         sc->vpos -= max(sc->vpage-sc->vscroll,1)*speed;break;
  858.     case WA_RTPAGE:
  859.         sc->hpos += max(sc->hpage-sc->hscroll,1)*speed;break;
  860.     case WA_DNPAGE:
  861.         sc->vpos += max(sc->vpage-sc->vscroll,1)*speed;break;
  862.     case WA_LFLINE:
  863.         sc->hpos -= speed*sc->hscroll;break;
  864.     case WA_UPLINE:
  865.         sc->vpos -= speed*sc->vscroll;break;
  866.     case WA_RTLINE:
  867.         sc->hpos += speed*sc->hscroll;break;
  868.     case WA_DNLINE:
  869.         sc->vpos += speed*sc->vscroll;break;
  870.     case WIN_START:
  871.         sc->vpos = 0;
  872.     case LINE_START:
  873.         sc->hpos = 0; break;
  874.     case WIN_END:
  875.         sc->hpos = 0;sc->vpos = sc->vsize;break;
  876.     case LINE_END:
  877.         sc->hpos = sc->hsize; break;
  878.     }
  879. }
  880.  
  881. void scroll_window(WIN *win,int mode,GRECT *rect)
  882. {
  883.     GRECT area,work,work2;
  884.     reg DIAINFO *info = (DIAINFO *) win->dialog;
  885.     reg SCROLL *sc = win->scroll;
  886.     reg int dist_h,dist_v,old_h,old_v,clipped,depth;
  887.     int pxy[4];
  888.  
  889.     if (sc==NULL)
  890.         return;
  891.  
  892.     _arrow_window(sc,mode,1);
  893.  
  894.     sc->hpos = max(min(sc->hpos,sc->hsize-sc->hpage),0);
  895.     sc->vpos = max(min(sc->vpos,sc->vsize-sc->vpage),0);
  896.  
  897.     old_h = sc->px_hpos;
  898.     old_v = sc->px_vpos;
  899.     sc->px_hpos = sc->hpos*sc->px_hline;
  900.     sc->px_vpos = sc->vpos*sc->px_vline;
  901.  
  902.     if ((dist_h=(sc->px_hpos-old_h))!=0)
  903.         window_scroll_slider(win,HOR_SLIDER);
  904.  
  905.     if ((dist_v=(sc->px_vpos-old_v))!=0)
  906.         window_scroll_slider(win,VERT_SLIDER);
  907.  
  908.     if ((dist_h==0 && dist_v==0) || win->iconified || sc->scroll==FALSE)
  909.         return;
  910.  
  911.     if (rect)
  912.         area = *rect;
  913.     else
  914.     {
  915.         area = win->work;
  916.         area.g_x += sc->tbar_l;
  917.         area.g_y += sc->tbar_u;
  918.         if ((area.g_w-=sc->tbar_l+sc->tbar_r)<=0 || (area.g_h-=sc->tbar_u+sc->tbar_d)<=0)
  919.             return;
  920.     }
  921.  
  922.     if (win->redraw==NULL || _dia_len>0 || _popup)
  923.         redraw_window(win,&area);
  924.     else
  925.     {
  926.         if (info)
  927.             depth = (sc->obj==ROOT) ? MAX_DEPTH : 0;
  928.  
  929.         clipped = FALSE;
  930.         wind_update(BEG_UPDATE);
  931.         MouseOff();
  932.         window_first(win,&work);
  933.         if (work.g_w>0 && work.g_h>0)
  934.             for (;;)
  935.             {
  936.                 if (rc_intersect(&area,&work))
  937.                 {
  938.                     switch (rc_sc_scroll(&work,dist_h,dist_v,&work2))
  939.                     {
  940.                     case 2:
  941.                         rc_grect_to_array(&work2,pxy);
  942.                         vs_clip(win->vdi_handle,1,pxy);
  943.                         if (info)
  944.                             objc_draw(info->di_tree,sc->obj,depth,work2.g_x,work2.g_y,work2.g_w,work2.g_h);
  945.                         else
  946.                             (*(R_PROC) win->redraw)(win,&work2);
  947.                     case 1:
  948.                         rc_grect_to_array(&work,pxy);
  949.                         vs_clip(win->vdi_handle,1,pxy);
  950.                         clipped = (win->vdi_handle==x_handle);
  951.                         if (info)
  952.                             objc_draw(info->di_tree,sc->obj,depth,work.g_x,work.g_y,work.g_w,work.g_h);
  953.                         else
  954.                             (*(R_PROC) win->redraw)(win,&work);
  955.                     }
  956.                 }
  957.  
  958.                 if (clipped)
  959.                     _clip_rect(&desk);
  960.  
  961.                 window_next(win,&work);
  962.                 if (work.g_w<=0 || work.g_h<=0)
  963.                     break;
  964.             }
  965.  
  966.         MouseOn();
  967.         wind_update(END_UPDATE);
  968.     }
  969. }
  970.